/**********************************************************************
 * Copyright: (C)2024 LingYun IoT System Studio
 * Author: LiJiahui<2199250859@qq.com>
 *
 * Description: UART communication module implementation.
 * Integrates ring buffer, ISR, and a generic data parser for bare-metal.
 *
 * ChangeLog:
 * Version    Date       Author            Description
 * V1.0.0  2025.07.26    LiJiahui      Release initial version (modularized)
 * V1.1.0  2025.07.26    LiJiahui      Full bare-metal ring buffer and parser integration
 * V2.0.0  2025.07.26    LiJiahui      Reconstruction processing function part
 *
 ***********************************************************************/

#include "uart_comm.h"
#include <string.h>
#include <stdio.h>

// --- 环形缓冲区定义 (文件内部使用) ---
static uint8_t rx_ring_buffer[RX_RING_BUFFER_SIZE];
static volatile uint16_t rx_ring_head = 0; // 写指针 (ISR更新)
static volatile uint16_t rx_ring_tail = 0; // 读指针 (数据处理层更新)

// --- 单字节接收缓冲区 (HAL库要求) ---
static uint8_t uart_rx_byte_buffer[1];

// --- 内部解析器工作缓冲区 ---
static char parser_working_buffer[PARSER_WORKING_BUFFER_SIZE];
static uint16_t parser_current_len = 0;

// --- 外部 UART 句柄 (由 main.c 或 usart.c 定义) ---
extern UART_HandleTypeDef huart2;

// --- 统一封装的 UART 状态结构体定义 ---
UartCommData_t uart_comm_data;


// --- 内部辅助函数声明 ---
static bool parse_at_response(char *buffer, uint16_t len);
static bool parse_ipd_data(char *buffer, uint16_t len);
static bool parse_urc_messages(char *buffer, uint16_t len);

// --- UART 通信模块初始化 ---
void uart_comm_init(UART_HandleTypeDef *huart)
{
	// 初始化环形缓冲区指针
	rx_ring_head = 0;
	rx_ring_tail = 0;
	memset(rx_ring_buffer, 0, sizeof(rx_ring_buffer));

	// 初始化解析器工作缓冲区和标志
	parser_current_len = 0;
	memset(parser_working_buffer, 0, sizeof(parser_working_buffer));

	// 初始化封装的全局状态
	uart_comm_data.at_response_ready = false;
	memset(uart_comm_data.parsed_at_response, 0,
			sizeof(uart_comm_data.parsed_at_response));
	uart_comm_data.parsed_at_response_len = 0;
	uart_comm_data.received_ipd_data_ready = false;
	memset(uart_comm_data.received_ipd_data_buffer, 0,
			sizeof(uart_comm_data.received_ipd_data_buffer));
	uart_comm_data.received_ipd_data_len = 0;

	// 启动 UART 接收中断
	HAL_UART_Receive_IT(huart, uart_rx_byte_buffer, 1);
}

// --- UART 接收中断回调函数 (由 HAL 库调用) ---
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if (huart->Instance == USART2)
	{
		uint8_t received_byte = uart_rx_byte_buffer[0];

		BaseType_t xHigherPriorityTaskWoken = pdFALSE;

		uint16_t next_head = (rx_ring_head + 1) % RX_RING_BUFFER_SIZE;
		if (next_head != rx_ring_tail)
		{
			rx_ring_buffer[rx_ring_head] = received_byte;
			rx_ring_head = next_head;
		}

        if (xUartProcessTaskHandle != NULL)
        {
        	//发送通知，可进行上下文切换
            vTaskNotifyGiveFromISR(xUartProcessTaskHandle, &xHigherPriorityTaskWoken);
        }

		HAL_UART_Receive_IT(huart, uart_rx_byte_buffer, 1);

        // 如果有更高优先级的任务被唤醒，则进行上下文切换
        portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
	}
}

// --- 外部接口：数据处理函数 ---
void uart_process_received_data(void)
{
	uint8_t byte;

	// 只要环形缓冲区中有数据，就持续从其中读取
	while (rx_ring_head != rx_ring_tail)
	{
		// 安全地从环形缓冲区读取一个字节
		enter_critical_section();
		if (rx_ring_head == rx_ring_tail)
		{
			exit_critical_section();
			break;
		}
		byte = rx_ring_buffer[rx_ring_tail];
		rx_ring_tail = (rx_ring_tail + 1) % RX_RING_BUFFER_SIZE;
		exit_critical_section();

		// 检查解析器工作缓冲区是否溢出
		if (parser_current_len >= (PARSER_WORKING_BUFFER_SIZE - 1))
		{
			parser_current_len = 0; // 溢出则重置
		}

		parser_working_buffer[parser_current_len++] = byte;
		parser_working_buffer[parser_current_len] = '\0'; // 字符串函数需要空终止符

		// 依次尝试解析不同类型的消息
		if (parse_at_response(parser_working_buffer, parser_current_len))
		{
			// 成功解析后重置缓冲区
			parser_current_len = 0;
			memset(parser_working_buffer, 0, sizeof(parser_working_buffer));
		}
		else if (parse_ipd_data(parser_working_buffer, parser_current_len))
		{
			// 成功解析后重置缓冲区
			parser_current_len = 0;
			memset(parser_working_buffer, 0, sizeof(parser_working_buffer));
		}
		else if (parse_urc_messages(parser_working_buffer, parser_current_len))
		{
			// 成功解析后重置缓冲区
			parser_current_len = 0;
			memset(parser_working_buffer, 0, sizeof(parser_working_buffer));
		}
	}
}

// --- 内部辅助函数：解析 AT 响应 ---
static bool parse_at_response(char *buffer, uint16_t len)
{
	// 如果已经有 AT 响应待处理，则不进行新的解析
	if (uart_comm_data.at_response_ready)
	{
		return false;
	}

	bool message_found = false;

	// 检查 '>' 提示符
	if (len > 0 && buffer[len - 1] == '>')
	{
		message_found = true;
	}
	// 检查标准 AT 响应结尾
	else if (len >= 2 && buffer[len - 2] == '\r' && buffer[len - 1] == '\n')
	{
		if (strstr(buffer, "\r\nOK\r\n") != NULL
				|| strstr(buffer, "\r\nERROR\r\n") != NULL
				|| strstr(buffer, "\r\nFAIL\r\n") != NULL
				|| strstr(buffer, "\r\nSEND OK\r\n") != NULL
				|| strstr(buffer, "\r\nSEND FAIL\r\n") != NULL
				|| strstr(buffer, "\r\nCLOSED\r\n") != NULL)
		{
			message_found = true;
		}
	}

	if (message_found)
	{
		enter_critical_section();
		strncpy(uart_comm_data.parsed_at_response, buffer,
				PARSED_DATA_BUFFER_SIZE - 1);
		uart_comm_data.parsed_at_response[PARSED_DATA_BUFFER_SIZE - 1] = '\0';
		uart_comm_data.parsed_at_response_len = strnlen(
				uart_comm_data.parsed_at_response, PARSED_DATA_BUFFER_SIZE);
		uart_comm_data.at_response_ready = true;
		exit_critical_section();
	}

	return message_found;
}

// --- 内部辅助函数：解析 IPD 数据 ---
static bool parse_ipd_data(char *buffer, uint16_t len)
{
	// 如果已经有 IPD 数据待处理，则不进行新的解析
	if (uart_comm_data.received_ipd_data_ready)
	{
		return false;
	}

	char *ipd_start = strstr(buffer, "+IPD,");
	if (ipd_start == NULL)
		return false;

	char *colon_pos = strchr(ipd_start, ':');
	if (colon_pos == NULL)
		return false;

	int data_len_expected = 0;
	if (sscanf(ipd_start, "+IPD,%*d,%d", &data_len_expected) != 1
			&& sscanf(ipd_start, "+IPD,%d", &data_len_expected) != 1)
	{
		return false; // 解析 IPD 头部失败
	}

	uint16_t header_len = (colon_pos + 1) - buffer;
	uint16_t current_buffered_data_len = len - header_len;

	if (current_buffered_data_len >= data_len_expected)
	{
		if (data_len_expected
				> 0&& data_len_expected <= PARSED_DATA_BUFFER_SIZE)
		{
			enter_critical_section();
			memcpy(uart_comm_data.received_ipd_data_buffer, colon_pos + 1,
					data_len_expected);
			uart_comm_data.received_ipd_data_len = data_len_expected;
			uart_comm_data.received_ipd_data_ready = true;
			exit_critical_section();
		}
		return true;
	}

	return false;
}

// --- 内部辅助函数：解析 URC 和命令 ---
static bool parse_urc_messages(char *buffer, uint16_t len)
{
	// 处理 +BLECONN 和 +BLEDISCONN
	char *conn_status_prefix = strstr(buffer, "+BLECONN:");
	char *disconn_status_prefix = strstr(buffer, "+BLEDISCONN:");
	if (conn_status_prefix != NULL && strstr(conn_status_prefix, "\r\n") != NULL)
	{
		xEventGroupClearBits(xBLEEventGroup, BIT_BLE_DISCONNECTED);
		xEventGroupSetBits(xBLEEventGroup, BIT_BLE_CONNECTED);
		return true;
	}
	if (disconn_status_prefix != NULL
			&& strstr(disconn_status_prefix, "\r\n") != NULL)
	{
		xEventGroupClearBits(xBLEEventGroup, BIT_BLE_CONNECTED);
		xEventGroupSetBits(xBLEEventGroup, BIT_BLE_DISCONNECTED);
		return true;
	}

	// 处理 +WRITE 命令
	char *write_start = strstr(buffer, "+WRITE:");
	if (write_start != NULL && strstr(write_start, "\r\n") != NULL)
	{
		BleCommand_t command;
		if (strstr(write_start, "Yes") != NULL)
		{
			command.type = BLE_CMD_REPORT_NOW;
			xQueueSend(xBleCmdQueue, &command, 0);
		}
		else if (strstr(write_start, "Warning") != NULL)
		{
			command.type = BLE_CMD_BEEPER_WARNING;
			xQueueSend(xBleCmdQueue, &command, 0);
		}
		return true;
	}

	return false;
}

